﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using TCC.CMFlow.Models;
using TCC.CMFlow.Contexts;

namespace TCC.CMFlow.Controllers
{
    [Authorize]
    public class PerfilAcessoController : Controller
    {
        private DataContext db = new DataContext();

        // GET: /PerfilAcesso/
        [AuthorizeUserAttribute(Modulo = eModulosSistema.PerfisAcesso)]
        public ActionResult Index()
        {
            List<SelectListItem> itemsStatus = new List<SelectListItem>();
            itemsStatus.Add(new SelectListItem { Text = "Ativo", Value = "1" });
            itemsStatus.Add(new SelectListItem { Text = "Inativo", Value = "2" });
            ViewBag.PerfilStatus = new SelectList(itemsStatus, "Value", "Text");

            return View(db.PerfilAcesso.ToList());
        }

        //
        // POST: /Account/Index
        [HttpPost]
        [ValidateAntiForgeryToken]
        [AuthorizeUserAttribute(Modulo = eModulosSistema.PerfisAcesso, Permissao = ePermissoes.Consultar)]
        public ActionResult Index(string codigo, string nome, string PerfilStatus)
        {
            long _codigo;
            long.TryParse(codigo, out _codigo);

            int _UserStatus;
            int.TryParse(PerfilStatus, out _UserStatus);

            List<SelectListItem> itemsStatus = new List<SelectListItem>();
            itemsStatus.Add(new SelectListItem { Text = "Ativo", Value = "1" });
            itemsStatus.Add(new SelectListItem { Text = "Inativo", Value = "2" });
            ViewBag.PerfilStatus = new SelectList(itemsStatus, "Value", "Text");

            var perfisacesso = from p in db.PerfilAcesso
                               select p;

            if (_codigo > 0)
            {
                perfisacesso = perfisacesso.Where(p => p.ID == _codigo);
            }

            if (!String.IsNullOrEmpty(nome))
            {
                perfisacesso = perfisacesso.Where(p => p.Nome.ToUpper().Contains(nome.ToUpper()));
            }

            if (_UserStatus == (int)SituacaoId.Ativo)
            {
                perfisacesso = perfisacesso.Where(PerfilAcesso.IsAtivoExpression);
            }
            else if (_UserStatus == (int)SituacaoId.Inativo)
            {
                perfisacesso = perfisacesso.Where(PerfilAcesso.IsInativoExpression);
            }

            perfisacesso = perfisacesso.OrderBy(p => p.ID);

            return View(perfisacesso.ToList());
        }

        // GET: /PerfilAcesso/Details/5
        [AuthorizeUserAttribute(Modulo = eModulosSistema.PerfisAcesso, Permissao = ePermissoes.Visualizar)]
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            PerfilAcesso perfilacesso = db.PerfilAcesso.Find(id);
            if (perfilacesso == null)
            {
                return HttpNotFound();
            }
            return View(perfilacesso);
        }

        // GET: /PerfilAcesso/Create
        [AuthorizeUserAttribute(Modulo = eModulosSistema.PerfisAcesso, Permissao = ePermissoes.Incluir, isModal = true)]
        public ActionResult Create()
        {
            return PartialView();
        }

        // POST: /PerfilAcesso/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include="ID,Nome,Descricao,InicioVigencia,FimVigencia")] PerfilAcesso perfilacesso)
        {
            if (perfilacesso.InicioVigencia > perfilacesso.FimVigencia)
            {
                ModelState.AddModelError("Date", "Data fim não pode ser menor que a data início");
                return PartialView();
            }

            if (ModelState.IsValid)
            {
                db.PerfilAcesso.Add(perfilacesso);
                db.SaveChanges();
                return Json(new { success = true });
            }

            return PartialView(perfilacesso);
        }

        // GET: /PerfilAcesso/Edit/5
        [AuthorizeUserAttribute(Modulo = eModulosSistema.PerfisAcesso, Permissao = ePermissoes.Editar, isModal = true)]
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            PerfilAcesso perfilacesso = db.PerfilAcesso.Find(id);
            if (perfilacesso == null)
            {
                return HttpNotFound();
            }
            return PartialView(perfilacesso);
        }

        // POST: /PerfilAcesso/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include="ID,Nome,Descricao,InicioVigencia,FimVigencia")] PerfilAcesso perfilacesso)
        {
            if (perfilacesso.InicioVigencia > perfilacesso.FimVigencia)
            {
                ModelState.AddModelError("Date", "Data fim não pode ser menor que a data início");
                return PartialView();
            }

            if (ModelState.IsValid)
            {
                db.Entry(perfilacesso).State = EntityState.Modified;
                db.SaveChanges();

                return Json(new { success = true });
            }
            return PartialView(perfilacesso);
        }

        // GET: /PerfilAcesso/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            PerfilAcesso perfilacesso = db.PerfilAcesso.Find(id);
            if (perfilacesso == null)
            {
                return HttpNotFound();
            }
            return PartialView(perfilacesso);
        }

        // POST: /PerfilAcesso/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            PerfilAcesso perfilacesso = db.PerfilAcesso.Find(id);
            db.PerfilAcesso.Remove(perfilacesso);
            db.SaveChanges();
            return Json(new { success = true });
        }

        // GET: /PerfilAcesso/Delete/5
        [AuthorizeUserAttribute(Modulo = eModulosSistema.PerfisAcesso, Permissao = ePermissoes.Excluir, isModal = true)]
        public ActionResult Inactivate(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            PerfilAcesso perfilacesso = db.PerfilAcesso.Find(id);
            if (perfilacesso == null)
            {
                return HttpNotFound();
            }
            return PartialView(perfilacesso);
        }

        // POST: /PerfilAcesso/Delete/5
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Inactivate(int id, DateTime? FimVigencia)
        {
            if (FimVigencia < DateTime.Today)
            {
                ModelState.AddModelError("Date", "O fim da vigência não pode ser retroativo.");
                return PartialView();
            }

            PerfilAcesso perfilacesso = db.PerfilAcesso.Find(id);
            if (perfilacesso.InicioVigencia > FimVigencia)
            {
                ModelState.AddModelError("Date", "Data fim não pode ser menor que a data início.");
                return PartialView();
            }

            if (ModelState.IsValid)
            {
                perfilacesso.FimVigencia = FimVigencia;

                db.Entry(perfilacesso).State = EntityState.Modified;
                db.SaveChanges();
                return Json(new { success = true });
            }
            return PartialView(perfilacesso);
        }

        //
        // GET: /PerfilAcessoConfiguracao/Configurar
        public ActionResult PerfilAcessoMenus(int? PerfilAcessoID)
        {
            var menuSistema = db.MenuSistema.Include(m => m.ModulosSistema);
            ViewData["PerfilAcessoID"] = PerfilAcessoID;

            return PartialView(menuSistema);
        }

        //
        // GET: /PerfilAcessoConfiguracao/Configurar
        [AuthorizeUserAttribute(Modulo = eModulosSistema.PerfisAcesso, Permissao = ePermissoes.Editar, isModal = true)]
        public ActionResult ConfigurarPermissao(int? perfilAcessoID, int? moduloSistemaID)
        {
            if (perfilAcessoID == null || moduloSistemaID == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var selectedValues = new int[]{};
            var perfilacessoconfiguracao = (from c in db.PerfilAcessoConfiguracao
                                            where c.ModuloSistema.ID == moduloSistemaID &&
                                                  c.PerfilAcesso.ID == perfilAcessoID
                                            select c).FirstOrDefault();

            if (perfilacessoconfiguracao != null)
            {
                selectedValues = perfilacessoconfiguracao.Permissoes.Where(p => p != null).Select(p => p.ID).ToArray();
            }

            ViewBag.PerfilAcessoPermissoes = new MultiSelectList(db.Permissao, "ID", "Descricao", selectedValues);

            return PartialView(perfilacessoconfiguracao);
        }

        //
        // POST: /PerfilAcessoConfiguracao/Configurar
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult ConfigurarPermissao(int? PerfilAcessoID, int? ModuloSistemaID, int[] PermissaoList)
        {
            if (PerfilAcessoID == null || ModuloSistemaID == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var perfilAcessoConfiguracao = (from p in db.PerfilAcessoConfiguracao
                                            where p.PerfilAcesso.ID == PerfilAcessoID &&
                                                  p.ModuloSistema.ID == ModuloSistemaID
                                            select p).FirstOrDefault();

            if (ModelState.IsValid)
            {
                if (perfilAcessoConfiguracao == null)
                {
                    perfilAcessoConfiguracao = db.PerfilAcessoConfiguracao.Create();
                    perfilAcessoConfiguracao.PerfilAcessoID = PerfilAcessoID.Value;
                    perfilAcessoConfiguracao.ModuloSistemaID = ModuloSistemaID.Value;

                    db.PerfilAcessoConfiguracao.Add(perfilAcessoConfiguracao);
                    db.SaveChanges();

                    perfilAcessoConfiguracao = db.PerfilAcessoConfiguracao.Find(perfilAcessoConfiguracao.ID);
                }

                var permissoesAtuais = perfilAcessoConfiguracao.Permissoes.ToList();
                var permissoes = (from p in db.Permissao
                                  where PermissaoList.Contains(p.ID)
                                  select p).ToList();

                var permissoesAdd = permissoes.Except(permissoesAtuais, new LambdaComparer<Permissao>((a, b) => a.ID == b.ID, a => (int)a.ID));
                var permissoesDel = permissoesAtuais.Except(permissoes, new LambdaComparer<Permissao>((a, b) => a.ID == b.ID, a => (int)a.ID));

                foreach (var addItem in permissoesAdd)
                {
                    perfilAcessoConfiguracao.Permissoes.Add(addItem);
                }

                foreach (var delItem in permissoesDel)
                {
                    perfilAcessoConfiguracao.Permissoes.Remove(delItem);
                }

                db.Entry(perfilAcessoConfiguracao).State = EntityState.Modified;
                db.SaveChanges();

                return Json(new { success = true });
            }

            var selectedValues = perfilAcessoConfiguracao.Permissoes
                                                         .Where(p => p != null)
                                                         .Select(p => p.ID).ToArray();
            ViewBag.PerfilAcessoPermissoes = new MultiSelectList(db.Permissao, "ID", "Descricao", selectedValues);

            return PartialView(perfilAcessoConfiguracao);
        }

        //
        // GET: /PerfilAcessoConfiguracao/DeletePermissao
        [AuthorizeUserAttribute(Modulo = eModulosSistema.PerfisAcesso, Permissao = ePermissoes.Editar, isModal = true)]
        public ActionResult DeletePermissao(int? perfilAcessoID, int? moduloSistemaID)
        {
            if (perfilAcessoID == null || moduloSistemaID == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            var perfilacessoconfiguracao = (from c in db.PerfilAcessoConfiguracao
                                            where c.ModuloSistema.ID == moduloSistemaID &&
                                                  c.PerfilAcesso.ID == perfilAcessoID
                                            select c).FirstOrDefault();

            return PartialView(perfilacessoconfiguracao);
        }

        // POST: /PerfilAcessoConfiguracao/DeletePermissao/5
        [HttpPost, ActionName("DeletePermissao")]
        [ValidateAntiForgeryToken]
        public ActionResult DeletePermissaoConfirmed(int perfilAcessoID, int moduloSistemaID)
        {
            var perfilacessoconfiguracao = (from c in db.PerfilAcessoConfiguracao
                                            where c.ModuloSistema.ID == moduloSistemaID &&
                                                  c.PerfilAcesso.ID == perfilAcessoID
                                            select c).FirstOrDefault();
            if (perfilacessoconfiguracao != null)
            {
                db.PerfilAcessoConfiguracao.Remove(perfilacessoconfiguracao);
                db.SaveChanges();
            }
            
            return Json(new { success = true });
        }

        // GET: /PerfilAcesso/Permissoes/5
        public ActionResult Permissoes(int perfilAcessoID, int moduloSistemaID)
        {
            var perfilAcessoConfiguracao = (from p in db.PerfilAcessoConfiguracao
                                            where p.ModuloSistema.ID == moduloSistemaID &&
                                                  p.PerfilAcesso.ID == perfilAcessoID
                                            select p).FirstOrDefault();

            if (perfilAcessoConfiguracao == null || perfilAcessoConfiguracao.Permissoes == null)
                return Content("N/A");

            return Content(string.Join(", ", perfilAcessoConfiguracao.Permissoes.Select(p => p.Descricao).ToArray()));
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }

    }
}
